Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Положительный UPDATE (NetWork)
Author Message
NetWork
Участник форума



Joined: 11 May 2007
Posts: 46
Карма: -4
   поощрить/наказать


PostPosted: Thu Nov 22, 2007 5:43 pm (написано за 12 секунд)
   Post subject: Положительный UPDATE
Reply with quote

Возможно, этот вопрос покажется странным, но я все-таки хочу услышать, что об этом думаю люди.

На сайте была задача сделать модуль который управляет баннерами на сайте. Чтобы менеджер мог выбрать какой баннер показывать и сколько раз.

Допустим, менеджер начисляет на определённы баннер 100 000 показов. С каждым показом происходит SQL UPDATE, и кол-во показов уменьшается на 1.

Но вопрос в том, что будет, если у баннера изначально 1 показ. Начинается запуск скрипта показа баннера. Он проверяет, есть ли показы у баннера, и так как там 1 он начинает выбирать файл и т.д. Перед этим, правда, идут всякие проверки и т.д. И вот только потом в конце система отнимает 1 показ и у баннера теперь 0 показов.

Меня смущает то, что вдруг, в то время как будет выполняться скрипт система начнёт показывать баннер другому пользователю. И получиться так, что один выполниться быстрее и будет 0, а другой уже проверит, что у пользователя есть показ 1 и продолжит выполнять показ. Самое плохое, что в конце система отнимет 1 от 0 и будет -1.

СКОРОСТЬ ВЫПОЛНЕНИЯ PHP СКРИПТА: 0.09071

Вот такое вот реально при посещаемости сайта в 1 000 000 хитов в день? И как проще избежать такое.
Back to top
View user's profile Send private message
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 197
   поощрить/наказать

Location: 007 495

PostPosted: Thu Nov 22, 2007 6:09 pm (спустя 26 минут; написано за 3 минуты 8 секунд)
   Post subject:
Reply with quote

NetWork
Ну, навскидку можно что-нибудь подобное использовать:


Вначале делаете
Code (SQL): скопировать код в буфер обмена
UPDATE `sometable` SET `banners`=`banners`-1 WHERE `id`=... AND `banners`>0
Потом смотрите mysql_affected_rows() для запроса, и если оно равно нулю, значит он уже кому показывается, и выбираете другой баннер (или заканчиваете работу) :). Ну а иначе (mysql_affected_rows()==1) это значит, что всё ok и показываете текущий баннер.

Необходимую блокировку база сделает сама.
Back to top
View user's profile Send private message Send e-mail
NetWork
Участник форума



Joined: 11 May 2007
Posts: 46
Карма: -4
   поощрить/наказать


PostPosted: Thu Nov 22, 2007 6:36 pm (спустя 26 минут; написано за 4 минуты 7 секунд)
   Post subject:
Reply with quote

Ну, так я в самом начале проверяю, есть ли показы у баннера.

Дело в том, что вдруг в одну секунду на сайт зайдут 2 пользователя и им покажется один и тот же баннер у которого 1 показ всего. И так как если один скрипт ещё не выполнился до конца, а второй уже начал выполнятся, то получиться один только собирается отнять показ у баннера, а другой уже проверил, что показ есть, и будет отнимать потом, но только уже от 0 т.к. перед этим один уже отнял от 1-го 1. Или такое быть не может?
Back to top
View user's profile Send private message
NetWork
Участник форума



Joined: 11 May 2007
Posts: 46
Карма: -4
   поощрить/наказать


PostPosted: Thu Nov 22, 2007 7:00 pm (спустя 23 минуты; написано за 1 минуту 8 секунд)
   Post subject:
Reply with quote

Всё разобрался. Я просто забыл, что можно просто WHERE поставить и не допустить вычитания 1 от 0. UPDATE показы SET активные = активные - 1 WHERE активные > 0
Back to top
View user's profile Send private message
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 197
   поощрить/наказать

Location: 007 495

PostPosted: Thu Nov 22, 2007 7:09 pm (спустя 9 минут; написано за 24 секунды)
   Post subject:
Reply with quote

NetWork
Заметьте, что лучше это делать вначале работы, чтобы не делать лишнего :).
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML